<?php
/*!
	\file class.MQ.php
	\brief Contains the definition for the MessageQueue class.
*/

/*!
	\class MQ
	\author Alex McClung
	\date Created: October 21, 2007
	\date Modified: Octiber 21, 2007
	\brief Messaging class used to store programmatic status messages.
	
	This class is able to be called from a global scope, once a MQ object has been instantiated. For example,
	after calling:
		$q = new MQ();
		
	It is now possible to use any of the methods in this class in the following manner:
		MQ::Push(...);
		MQ::SetStream(...);
		MQ::Print();
	
	All the messages are stored in the global variable $GLOBALS[_MQ][_MQ_MESSAGES]
*/

// MessageQueue stream types
define('MQ_OK', 	 "MQ_OK");		// Normal / Succesful status messages go here
define('MQ_ERROR',   "MQ_ERROR");		// Error messages go here
define('MQ_WARNING', "MQ_WARNING");	// Warning messages go here
define('MQ_DEBUG',   "MQ_DEBUG");		// Debug messages go here

// Global variable access
define('_MQ',          "MQ"          );
define('_MQ_MESSAGES', "MQ_MESSAGES" );
define('_MQ_STREAMS',  "MQ_STREAMS"  );

// Stream enable/disable qualifiers
define('ENABLED',  true  );
define('DISABLED', false );

class MQ
{
	
	/*!
		\brief Class constructor
		\returns Object
		
		Turns all streams on by default
	*/
	function __construct()
	{
		$GLOBALS[_MQ][_MQ_MESSAGES] = array();
		$GLOBALS[_MQ][_MQ_STREAMS]  = array();
		
		// set all streams to on
		MQ::Enable(MQ_OK);
		MQ::Enable(MQ_ERROR);
		MQ::Enable(MQ_WARNING);
		MQ::Enable(MQ_DEBUG);
	}
	
	/*!
		\brief Enables a message stream
		\param $streamID - stream identifier to enable
	*/
	public function Enable($streamID)
	{
		$GLOBALS[_MQ][_MQ_STREAMS][$streamID] = ENABLED;
	}
	
	/*!
		\brief Disables a message stream
		\param $streamID - stream identifier to disable
	*/
	public function Disable($streamID)
	{
		$GLOBALS[_MQ][_MQ_STREAMS][$streamID] = DISABLED;
	}
	
	/*!
		\brief Inserts a new message into the queue
		\param $msg    - string text of the message
		\param $stream - ID of the stream to insert the message into
	*/
	public function Push($msg, $stream)
	{
		$GLOBALS[_MQ][_MQ_MESSAGES][] = array("msg"=>$msg, "stream"=>$stream);
	}
	
	/*!
		\brief Inserts a new message into the OK queue
		\param $msg    - string text of the message
	*/
	public function OK($msg)
	{
		MQ::Push($msg, MQ_OK);
	}
	
	/*!
		\brief Inserts a new message into the error queue
		\param $msg    - string text of the message
	*/
	public function Error($msg)
	{
		MQ::Push($msg, MQ_ERROR);
	}
	
	/*!
		\brief Inserts a new message into the warning queue
		\param $msg    - string text of the message
	*/
	public function Warn($msg)
	{
		MQ::Push($msg, MQ_WARNING);
	}
	
	/*!
		\brief Inserts a new message into the debug queue
		\param $msg    - string text of the message
	*/
	public function Debug($msg)
	{
		MQ::Push($msg, MQ_DEBUG);
	}
	
	/*!
		\brief Returns a message off the end of the message queue (returns last message pushed)
		\returns string
	*/
	public function Pop()
	{
		return array_pop($GLOBALS[_MQ][_MQ_MESSAGES]);
	}
	
	/*!
		\brief Returns a message off the front of the message queue (returns first message pushed)
		\returns string
	*/
	public function Shift()
	{
		return array_shift($GLOBALS[_MQ][_MQ_MESSAGES]);
	}
	
	/*!
		\brief Clears all messages in the queue
		\returns nothing
	*/
	public function Flush()
	{
		$GLOBALS[_MQ][_MQ_MESSAGES] = array();
	}
	
	/*!
		\brief Returns the number of messages in a stream
		\param $stream - stream type
		\returns int
	*/
	function NumMessages($stream)
	{
		$n=0;
		foreach($GLOBALS[_MQ][_MQ_MESSAGES] as $message)
			if($message['stream']==$stream)
				$n++;
		return $n;
	}
	
	/*!
		\brief Prints all messages in the queue to standard out
		\returns nothing
		
		All messages will be enclosed in &lt;div&gt; tags with a CSS style corresponding to
		the message type (&lt;div class="S_OK"&gt;, &lt;div class="S_DEBUG"&gt;, etc). Once this
		function is called, the message queue will be empty.
	*/
	public function PrintQ()
	{
		$s_last = null;
		if(count($GLOBALS[_MQ][_MQ_MESSAGES]) == 0)
			return;
		while($m = MQ::Shift())
		{
			$stream  = $m['stream'];
			$message = $m['msg'];
			if($GLOBALS[_MQ][_MQ_STREAMS][$stream] === ENABLED)
			{
				if($stream != $s_last)
				{
					if($s_last != null)
						echo "</div>\n";
					echo "<div class=\"$stream\">";
				}
				echo "$message<br />\n";
				$s_last = $stream;
			}
		}
		if($s_last != null)
			echo "</div><br />\n";
	}
	
	/*!
		\brief Alternate function to PrintQueue() - generates HTML and returns it as a string
		\returns HTML string
	*/
	public function ToHTML()
	{
		$s_last = null;
		if(count($GLOBALS[_MQ][_MQ_MESSAGES]) == 0)
			return;
		$markup = "";
		while($m = MQ::Shift())
		{
			$stream  = $m['stream'];
			$message = $m['msg'];
			if($GLOBALS[_MQ][_MQ_STREAMS][$stream] === ENABLED)
			{
				if($stream != $s_last)
				{
					if($s_last != null)
						$markup .= "</div>\n";
					$markup .= "<div class=\"$stream\">";
				}
				$markup .= "$message<br />\n";
				$s_last = $stream;
			}
		}
		$markup .= "</div><br />\n";
		return $markup;
	}
}

// create a global class instance of the queue for everybody to use
if(!isset($GLOBALS[_MQ]['instance']))
	$GLOBALS[_MQ]['instance'] = new MQ();
?>